package com.dz.risk.custom.dynamic;

import com.dz.risk.common.utils.JepUtils;
import com.dz.risk.exception.VerifyException;
import com.dz.risk.pojo.domain.ReportFormsDataValueEntity;
import com.dz.risk.service.ReportFormsDataValueService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 公式计算处理
 *
 * @author Doke
 * @date 2021/8/10 17:36
 */
@Component
@Slf4j
public class FormulaCalculation {

    private final ReportFormsDataValueService reportFormsDataValueService;

    @Autowired
    public FormulaCalculation(ReportFormsDataValueService reportFormsDataValueService) {
        this.reportFormsDataValueService = reportFormsDataValueService;
    }

    /**
     * 验证公式(只作为验证公式正确性使用)
     *
     * @param formulaDetails 公式详情
     * @param parseFormula   公式参与的参数
     */
    public void checkCalculation(String formulaDetails, List<String> parseFormula) {
        Assert.notEmpty(parseFormula, "参数集合不能为空");
        Assert.notNull(formulaDetails, "公式不能为空");

        int initialCapacity = (int) (parseFormula.size() / 0.75 + 1);
        Map<String, Double> paramsMap = new HashMap<>(initialCapacity);

        //遍历参数集合,获取对应的值,随便获取一个有数据的值版本
        parseFormula.forEach(a -> paramsMap.put(a, getIndexValue(a)));
        //公式计算
        JepUtils.parseExpression(formulaDetails, paramsMap);
    }

    /**
     * 根据单元格编号获取数据值
     *
     * @param tableCellSerialNumber 单元格编号
     * @return 单元格值
     */
    private Double getIndexValue(String tableCellSerialNumber) {
        List<ReportFormsDataValueEntity> reportFormsDataValueEntities = reportFormsDataValueService.selectByCellSerialNumberAndDataValueIsNotNull(tableCellSerialNumber);

        //判断该报表是否可是采用模板源数据
        if (CollectionUtils.isEmpty(reportFormsDataValueEntities)) {
            throw new VerifyException(tableCellSerialNumber + "还未存在任何具体数据值,无法进行验证计算");
        }

        double value;
        try {
            value = Double.parseDouble(reportFormsDataValueEntities.get(0).getDataValue());
        } catch (Exception e) {
            throw new VerifyException("单元格" + reportFormsDataValueEntities.get(0).getTableCellSerialNumber() + "的值无法转换为数字类型,无法进行计算");
        }
        return value;
    }
}
